#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gmssl/sm3.h>

#define SM3_DIGEST_LENGTH 32 // SM3 摘要长度为 32 字节

void print_usage() {
    fprintf(stderr, "Usage: sm3_digest <input_file> <output_file>\n");
}

int main(int argc, char *argv[]) {
    if (argc != 3) {
        print_usage();
        return EXIT_FAILURE;
    }

    const char *input_file = argv[1];
    const char *output_file = argv[2];

    // 打开输入文件
    FILE *fp_input = fopen(input_file, "rb");
    if (!fp_input) {
        perror("Error opening input file");
        return EXIT_FAILURE;
    }

    // 读取输入文件内容
    unsigned char buffer[1024];
    size_t bytes_read;
    SM3_CTX ctx;
    unsigned char digest[SM3_DIGEST_LENGTH];

    // 初始化 SM3 上下文
    sm3_init(&ctx);

    // 逐块读取文件并更新摘要
    while ((bytes_read = fread(buffer, 1, sizeof(buffer), fp_input)) > 0) {
        sm3_update(&ctx, buffer, bytes_read);
    }

    // 检查读取文件时是否发生错误
    if (ferror(fp_input)) {
        perror("Error reading input file");
        fclose(fp_input);
        return EXIT_FAILURE;
    }

    // 完成摘要计算
    sm3_finish(&ctx, digest); // 使用 sm3_finish 替代 sm3_final
    fclose(fp_input);

    // 打开输出文件
    FILE *fp_output = fopen(output_file, "wb");
    if (!fp_output) {
        perror("Error opening output file");
        return EXIT_FAILURE;
    }

    // 将摘要写入输出文件
    if (fwrite(digest, 1, sizeof(digest), fp_output) != sizeof(digest)) {
        perror("Error writing output file");
        fclose(fp_output);
        return EXIT_FAILURE;
    }

    fclose(fp_output);

    printf("SM3 digest computed and written to %s\n", output_file);
    return EXIT_SUCCESS;
}
